//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//********************************************************* 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Collections;
using Microsoft.TridentWordAddIn.Common;

namespace Microsoft.TridentWordAddIn.Presentation
{
    /// <summary>
    /// The class CustomTypeInitializer
    /// </summary>
    public partial class CustomTypeInitializer : BaseTypeInitializer
    {
        private string value;
        private bool isValid = true;
        private List<ComplexInitializer> fields = new List<ComplexInitializer>();

        /// <summary>
        /// Initializes a new instance of the <see cref="CustomTypeInitializer"/> class.
        /// </summary>
        public CustomTypeInitializer(List<ComplexInitializer> fields)
        {
            InitializeComponent();
            this.fields = fields;
        }

        #region Public Methods

        /// <summary>
        /// Determines whether this instance is valid.
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if this instance is valid; otherwise, <c>false</c>.
        /// </returns>
        public override bool IsValid
        {
            get
            {
                return this.isValid;
            }
        }

        /// <summary>
        /// Gets the result.
        /// </summary>
        /// <returns></returns>
        public override object GetResult()
        {
            this.UpdateResult();
            this.SerializedResult();
            return this.value;
        }

        /// <summary>
        /// Sets the result.
        /// </summary>
        /// <param name="result">The result.</param>
        public override void SetResult(object result)
        {
            this.value = result.ToString();
            CreateUI();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Creates the UI.
        /// </summary>
        private void CreateUI()
        {
            int index = 0;
            tlbctrControls.Controls.Clear();
            foreach (ComplexInitializer initializer in this.fields)
            {
                if (initializer.IsRoot)
                {
                    lblTitle.Text = initializer.Label + " Details";
                    continue;
                }

                Control label = GetLabelControl(initializer.Label);
                Control textBox = GetTextBox(initializer.Value, false);

                tlbctrControls.Controls.Add(label, 0, index);
                tlbctrControls.Controls.Add(textBox, 1, index);
                index++;
            }
        }

        /// <summary>
        /// Results this instance.
        /// </summary>
        /// <returns></returns>
        private void UpdateResult()
        {
            int index = 0;
            StringBuilder result = new StringBuilder();
            this.isValid = true;

            foreach (ComplexInitializer initializer in this.fields)
            {
                if (!initializer.IsRoot)
                {
                    TextBox textBox = tlbctrControls.GetControlFromPosition(1, index) as TextBox;
                    initializer.Value = textBox.Text;
                    if (initializer.Value.IsNullOrEmpty())
                    {
                        this.isValid = false;
                    }

                    index++;
                }
            }
        }

        /// <summary>
        /// Serializeds the result.
        /// </summary>
        private void SerializedResult()
        {
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(this.value);
            foreach (XmlNode node in xmlDocument.ChildNodes)
            {
                if (node.NodeType == XmlNodeType.Element)
                {
                    foreach (XmlNode childNode in node.ChildNodes)
                    {
                        foreach (ComplexInitializer initializer in this.fields)
                        {
                            if (initializer.Label.Equals(childNode.Name))
                            {
                                childNode.InnerText = initializer.Value;
                                break;
                            }
                        }
                    }
                }
            }

            this.value = xmlDocument.InnerXml;
        }

        /// <summary>
        /// Gets the label control.
        /// </summary>
        /// <param name="label">The label.</param>
        /// <returns></returns>
        private Control GetLabelControl(string label)
        {
            CustomLabel nameControl = new CustomLabel();
            nameControl.Left = 4;
            nameControl.Margin = new Padding(0, 8, 4, 0);
            nameControl.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;
            nameControl.Text = label;
            nameControl.AutoEllipsis = true;
            nameControl.IsRequiredField = false;
            return nameControl;
        }

        /// <summary>
        /// Gets the text box.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="isReadonly">if set to <c>true</c> [is readonly].</param>
        /// <returns></returns>
        private Control GetTextBox(object value, bool isReadonly)
        {
            TextBox textBox = new TextBox();
            textBox.ReadOnly = isReadonly;
            if (value != null)
            {
                textBox.Text = value.ToString();
            }

            textBox.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
            return textBox;
        }

        #endregion
    }
}
